package page

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"gspeed/bootstrap/global"
	"strconv"
	"strings"
)

type Page struct {
	List  interface{} `json:"list"`
	Count int64       `json:"count"`

	limit int    `json:"-"`
	page  int    `json:"-"`
	order string `json:"-"`
	field string `json:"-"`
}

func (p *Page) getParams(c *gin.Context) (page int, limit int, order string, field string) {
	page, _ = strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ = strconv.Atoi(c.DefaultQuery("limit", "10"))
	order = c.DefaultQuery("order", "desc")
	field = c.DefaultQuery("field", "updated_at")
	return page, limit, order, field
}

func (p *Page) GetScope(c *gin.Context, model interface{}) func(db *gorm.DB) *gorm.DB {
	p.page, p.limit, p.order, p.field = p.getParams(c)

	global.DB.Model(model).Count(&p.Count)
	return func(db *gorm.DB) *gorm.DB {
		limit := db.Offset(p.GetOffset()).Limit(p.GetLimit())
		if p.GetSort() != "" {
			limit.Order(p.GetSort())
		}
		return limit
	}
}

func (p *Page) GetPage() int {
	if p.page <= 0 {
		p.page = 1
	}
	return p.page
}

func (p *Page) GetOffset() int {
	return (p.GetPage() - 1) * p.GetLimit()
}

func (p *Page) GetLimit() int {
	if p.limit <= 0 {
		p.limit = 10
	}
	if p.limit >= 1000 {
		p.limit = 1000
	}
	return p.limit
}

func (p *Page) GetSort() string {
	if p.field == "" {
		return ""
	}

	switch strings.ToLower(p.order) {
	case "desc":
		p.order = "desc"
	case "asc":
		p.order = "asc"
	default:
		p.order = "desc"
	}
	return p.field + " " + p.order
}

func (p *Page) GetTag(c *gin.Context) string {
	page, limit, order, field := p.getParams(c)
	str := "page." + strconv.Itoa(page) + "-limit." + strconv.Itoa(limit)
	if order != "" && field != "" {
		str += "-order." + order + "-field." + field
	}
	return str
}
